﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace ajayumi.Platform.Win.ComboTree
{
    /// <summary>
    /// 组合树控件
    /// Author   : 黄乙冬
    /// Date     : 2011-09-13
    /// </summary>
    public class ComboTree : ComboBox
    {
        private bool isVisible = false;
        private const int WM_LBUTTONDOWN = 0x201, WM_LBUTTONDBLCLK = 0x203;
        ToolStripControlHost treeViewHost;
        ToolStripDropDown dropDown;

        public ComboTree()
        {
            this.DropDownStyle = ComboBoxStyle.DropDownList;
            TreeView treeView = new TreeView()
            {
                BorderStyle = BorderStyle.None,
                HideSelection = false,
                FullRowSelect = true
            };
            treeView.AfterSelect += new TreeViewEventHandler(treeView_AfterSelect);
            treeViewHost = new ToolStripControlHost(treeView);
            dropDown = new ToolStripDropDown();
            dropDown.Width = this.Width;
            dropDown.Items.Add(treeViewHost);
        }

        public virtual void treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            //this.Items.Clear();
            this.Invoke(new Action(this.Items.Clear));

            TreeNode node = this.TreeView.SelectedNode;
            //this.Items.Add(node.Text);
            this.Invoke(new Func<object, int>(this.Items.Add), new object[] { this.TreeView.SelectedNode.Text });
            this.Text = node.Text;
            //this.Name = TreeView.SelectedNode.Name;
            this.Tag = node.Tag;
            this.Focus();
            this.HideDropDown();
        }

        public void SetCurSelected(TreeNode node)
        {
            //this.TreeView.SelectedNode = node;
            //this.Items.Clear();
            //this.Items.Add(TreeView.SelectedNode.Text);
            //this.SelectedIndex = 0;
            //this.Name = TreeView.SelectedNode.Name;
            //this.Tag = TreeView.SelectedNode.Tag;

            this.SetSelectedNode(this.TreeView, node);
            this.Invoke(new Action(this.Items.Clear));

            if (InvokeRequired)
            {
                Func<object, int> func = new Func<object, int>(
                    (o) =>
                    {
                        int result = this.Items.Add(o);
                        return result;
                    });
                this.Invoke(func, new object[] { node.Text });
            }
            else { this.Items.Add(node.Text); }

            this.SetSelectedIndex(this, 0);
            this.SetTag(this, node.Tag);
        }

        private void SetTag(ComboTree control, object value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new Action<ComboTree, object>(this.SetTag), new object[] { control, value });
            }
            else
            { control.Tag = value; }
        }

        private void SetSelectedNode(TreeView control, TreeNode node)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new Action<TreeView, TreeNode>(this.SetSelectedNode), new object[] { control, node });
            }
            else
            { control.SelectedNode = node; }
        }

        private void SetSelectedIndex(ComboTree control, int value)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new Action<ComboTree, int>(this.SetSelectedIndex), new object[] { control, value });
            }
            else
            { control.SelectedIndex = value; }
        }

        public TreeView TreeView
        {
            get { return treeViewHost.Control as TreeView; }
        }

        /// <summary>
        /// 显示下拉框内容
        /// </summary>
        protected virtual void ShowDropDown()
        {
            if (dropDown != null)
            {
                int height = this.TreeView.ItemHeight;
                int count = this.TreeView.GetNodeCount(true);
                if (count > 0)
                { height = this.ItemHeight * (count + 1); }
                treeViewHost.Size = new Size(DropDownWidth - 2, height);
                dropDown.Show(this, 0, this.Height);
                this.isVisible = true;
            }
        }

        /// <summary>
        /// 隐藏下拉框内容
        /// </summary>
        protected virtual void HideDropDown()
        {
            if (dropDown != null)
            {
                dropDown.Close();
                this.isVisible = false;
            }
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_LBUTTONDBLCLK || m.Msg == WM_LBUTTONDOWN)
            {
                if (!this.isVisible)
                { ShowDropDown(); }
                else
                { this.HideDropDown(); }
                return;
            }
            base.WndProc(ref m);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (dropDown != null)
                {
                    dropDown.Dispose();
                    dropDown = null;
                    this.isVisible = false;
                }
            }
            base.Dispose(disposing);
        }
    }
}
